

#include "Od.h"
#include <algorithm>

DWORD dwOdBase = 0;

std::string WChar2Ansi(LPCWSTR pwszSrc)
{
	int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);

	if (nLen <= 0) return std::string("");

	char* pszDst = new char[nLen];
	if (NULL == pszDst) return std::string("");

	WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
	pszDst[nLen - 1] = 0;

	std::string strTemp(pszDst);
	delete[] pszDst;

	return strTemp;
}

std::string ws2s(std::wstring& inputws)
{
	return WChar2Ansi(inputws.c_str());
}

std::wstring Ansi2WChar(LPCSTR pszSrc, int nLen)
{
	int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0);
	if (nSize <= 0) return L"";

	WCHAR *pwszDst = new WCHAR[nSize + 1];
	if (NULL == pwszDst) return L"";

	MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, pwszDst, nSize);
	pwszDst[nSize] = 0;

	if (pwszDst[0] == 0xFEFF)                    // skip Oxfeff
		for (int i = 0; i < nSize; i++)
			pwszDst[i] = pwszDst[i + 1];

	std::wstring wcharString(pwszDst);
	delete pwszDst;

	return wcharString;
}

std::wstring s2ws(const std::string& s)
{
	return Ansi2WChar(s.c_str(), s.size());
}

std::wstring SignedToHex(int64_t value)
{
	std::wstring strret;
	wchar_t buff[16] = L"";
	if (value < 0)
	{
		int64_t uvalue = abs(value);
		strret = L"-";
		strret += _i64tow(uvalue, buff, 16);
	}else
		strret = _i64tow(value, buff, 16);

	std::transform(strret.begin(), strret.end(), strret.begin(), toupper);

	return strret;
}

bool WriteMemory(PBYTE BaseAddress, PBYTE Buffer, DWORD nSize)
{
	DWORD ProtectFlag = 0;
	if (VirtualProtectEx(GetCurrentProcess(), BaseAddress, nSize, PAGE_EXECUTE_READWRITE, &ProtectFlag))
	{
		memcpy(BaseAddress, Buffer, nSize);
		FlushInstructionCache(GetCurrentProcess(), BaseAddress, nSize);
		VirtualProtectEx(GetCurrentProcess(), BaseAddress, nSize, ProtectFlag, &ProtectFlag);
		return true;
	}
	return false;
}

void InstallJMP(PBYTE BaseAddress, MWORD Function)
{
#ifdef _WIN64
	BYTE move[] = { 0x48, 0xB8 };//move rax,xxL);
	BYTE jump[] = { 0xFF, 0xE0 };//jmp rax
	
	WriteMemory(BaseAddress, move, sizeof(move));
	BaseAddress += sizeof(move);
	
	WriteMemory(BaseAddress, (PBYTE)&Function, sizeof(MWORD));
	BaseAddress += sizeof(MWORD);
	
	WriteMemory(BaseAddress, jump, sizeof(jump));
#else
	BYTE jump[] = { 0xE9 };
	WriteMemory(BaseAddress, jump, sizeof(jump));
	BaseAddress += sizeof(jump);
	
	MWORD offset = Function - (MWORD)BaseAddress - 4;
	WriteMemory(BaseAddress, (PBYTE)&offset, sizeof(offset));
#endif // _WIN64
}

void InstallCall(PBYTE BaseAddress, MWORD Function)
{
#ifdef _WIN64

#else
	BYTE call[] = { 0xE8 };
	WriteMemory(BaseAddress, call, sizeof(call));
	BaseAddress += sizeof(call);

	MWORD offset = Function - (MWORD)BaseAddress - 4;
	WriteMemory(BaseAddress, (PBYTE)&offset, sizeof(offset));
#endif // _WIN64
}